package com.medisign.sign.log.service.impl;

import com.alibaba.fastjson.JSON;
import com.medisign.sign.log.config.SystemConfig;
import com.medisign.sign.log.dao.TbSignLogDao;
import com.medisign.sign.log.pojo.QTbSignFile;
import com.medisign.sign.log.pojo.QTbSignLog;
import com.medisign.sign.log.pojo.TbSignFile;
import com.medisign.sign.log.pojo.TbSignLog;
import com.medisign.sign.log.service.IRepairService;
import com.medisign.sign.log.vo.SignLogFileInfo;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@RequiredArgsConstructor
@Slf4j
@Service
public class RepairServiceImpl implements IRepairService {

    private final SystemConfig systemConfig;
    private final TbSignLogDao signLogDao;
    private final JPAQueryFactory jpaQueryFactory;

    static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Async
    @Override
    public String repairDate() {
        String baseSignLogPath = systemConfig.getPath().getSignLogPath();
        Long queryId = 0L;
        while (true) {
            long start = System.currentTimeMillis();
            Pageable pageable = PageRequest.of(0, 50);
            QTbSignLog qTbSignLog = QTbSignLog.tbSignLog;
            BooleanExpression whereExp = qTbSignLog.id.gt(queryId);
            List<TbSignLog> signLogList = jpaQueryFactory.select(qTbSignLog).from(qTbSignLog)
                    .where(whereExp)
                    .offset(pageable.getOffset())
                    .limit(pageable.getPageSize())
                    .fetchResults().getResults();
            log.info("查询文件耗时:[{}]ms", System.currentTimeMillis() - start);
            if (CollectionUtils.isEmpty(signLogList)) {
                break;
            }
            for (TbSignLog signLog : signLogList) {
                queryId = signLog.getId();
                String logPath = baseSignLogPath + signLog.getLogPath();
                SignLogFileInfo signLogFileInfo =  getFileDate(logPath);
                if (null == signLogFileInfo) {
                    continue;
                }
                signLog.setFileName("签名日志");
                signLog.setStartTime(signLogFileInfo.getStartTime());
                signLog.setEndTime(signLogFileInfo.getEndTime());
                this.signLogDao.save(signLog);
            }
        }
        log.info("填充文件时间执行完成");
        return "success";
    }

    public static SignLogFileInfo getFileDate(String filePath) {
        Date startDate = null;
        Date endDate = null;
        int rawCount = 1;
        File file = new File(filePath);
        if (!file.exists())
            return null;
        try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
            String firstLine = reader.readLine();
            startDate = parseDate(firstLine);
            endDate = startDate;
            String lastLine = null;
            String currentLine;
            while ((currentLine = reader.readLine()) != null) {
                lastLine = currentLine;
                rawCount++;
                Date currentRawDate = parseDate(lastLine);
                if (currentRawDate.getTime() < startDate.getTime())
                    startDate = currentRawDate;
                if (currentRawDate.getTime() > endDate.getTime())
                    endDate = currentRawDate;
            }
            log.info("第一行" + firstLine);
            log.info("最后一行" + lastLine);
            SignLogFileInfo signLogFileInfo = new SignLogFileInfo();
            signLogFileInfo.setRawCount(rawCount);
            signLogFileInfo.setStartTime(startDate);
            signLogFileInfo.setEndTime(endDate);
            return signLogFileInfo;
        } catch (IOException e) {
            log.error("{}", e);
            return null;
        }
    }

    private static Date parseDate(String line) {
        String[] split = line.split(",");
        String dateStrSpan = split[0];
        String dataStr = dateStrSpan.replace("[", "").replace("]", "");
        try {
            return sdf.parse(dataStr);
        } catch (ParseException e) {
            log.error("解析时间失败,line:[{}],错误信息:[{}]", line, e);
        }
        return null;
    }

    public static void main(String[] args) {
        String path = "D:\\工作\\环境\\浙一\\签署日志\\ee6.log";
        SignLogFileInfo fileDate = getFileDate(path);
        System.out.println(sdf.format(fileDate.getStartTime()));
        System.out.println(sdf.format(fileDate.getEndTime()));
        System.out.println(JSON.toJSONString(fileDate));
    }
}
